home *** CD-ROM | disk | FTP | other *** search
/ Archive Magazine CD 1995 / Archive Magazine CD 1995.iso / discs / prog_disc / volume_5 / issue_08 / boota / C-source / c / 1stUnMake < prev    next >
Encoding:
Text File  |  1991-12-16  |  24.8 KB  |  661 lines

  1. /* > c.1stUnMake  - (c) Paul Witheridge - Version 2.00 - 06 Dec 1991 */
  2.  
  3. /*===================================================================*/
  4. /*                                                                   */
  5. /*  1stUnMake  -  convert 1stWord+ document to text file file        */
  6. /*  ---------                                                        */
  7. /*                                                                   */
  8. /*  This utility converts 1stWord+ documents to plain text files,    */
  9. /*  deleting all the embedded 1stWord+ control information.          */
  10. /*                                                                   */
  11. /*  Note that this can also be done straight from 1stWord+ by        */
  12. /*  turning off the "WP" mode and saving to disk, but 1stUnMake      */
  13. /*  also deletes trailing blanks and can process multiple files.     */
  14. /*                                                                   */
  15. /*-------------------------------------------------------------------*/
  16. /*                                                                   */
  17. /*  COPYRIGHT NOTICE                                                 */
  18. /*                                                                   */
  19. /*  1stUnMake is subject to Copyright.                               */
  20. /*                                                                   */
  21. /*  Permission is granted by the author to any recipient of this     */
  22. /*  material to use and make/disseminate copies of the application   */
  23. /*  provided that no charges are made for doing so (other than to    */
  24. /*  cover any cost of media or postage) and that this notice is      */
  25. /*  included with all copies.                                        */
  26. /*                                                                   */
  27. /*===================================================================*/
  28.  
  29. #include "kernel.h"                     /* ARC specifics             */
  30. #include <ctype.h>                      /* Character handling        */
  31. #include <limits.h>                     /* Implementation limits     */
  32. #include <stddef.h>                     /* Standard definitions      */
  33. #include <stdio.h>                      /* Input/output              */
  34. #include <stdlib.h>                     /* General utilities         */
  35. #include <string.h>                     /* String handling           */
  36. #include "GetDirs.h"                    /* GetDirs header            */
  37. #include "ArgFuncs.h"                   /* Arg functions etc         */
  38. #include "Useful.h"                     /* Useful definitions        */
  39.  
  40. /*-------------------------------------------------------------------*/
  41. /*  Global data declarations and definitions.                        */
  42. /*-------------------------------------------------------------------*/
  43.  
  44. static char flags = '\0' ;              /* Processing flags          */
  45.   #define flgfnd 0x01                      /* Found file to process  */
  46.   #define flgftn 0x02                      /* Footnote found         */
  47.   #define flggrf 0x04                      /* Graphics found         */
  48.   #define flgovr 0x10                      /* Overwrite mode         */
  49.   #define flgrcs 0x20                      /* Recursive mode         */
  50.   #define flgtst 0x40                      /* Test mode              */
  51.  
  52. static int filecount = 0 ;              /* Count of files processed. */
  53.  
  54. static const char *argptr = NULL ;      /* Pointer to file spec.     */
  55. static const char *pfxptr = "_" ;       /* Pointer to output prefix  */
  56.  
  57. /*-------------------------------------------------------------------*/
  58. /*  Declare functions local in scope to this file.                   */
  59. /*-------------------------------------------------------------------*/
  60.  
  61. static enum boolean cnvtfunc(           /* Convert function          */
  62.   const char *path,
  63.   direntry *ptr) ;
  64.  
  65. static enum boolean footnotewarning(    /* Issue warning message      */
  66.   const char *filenameptr) ;
  67.  
  68. /*===================================================================*/
  69. /*                                                                   */
  70. /*  Main program                                                     */
  71. /*  ------------                                                     */
  72. /*                                                                   */
  73. /*  Analyse arguments. Then call the "GetDirentrys" function to read */
  74. /*  all the file-names in the specified directory (plus any sub      */
  75. /*  directories). Provide "GetDirentrys" with pointer to function    */
  76. /*  to process the specified files.                                  */
  77. /*                                                                   */
  78. /*===================================================================*/
  79.  
  80. int main(
  81.   const int argc,                     /* Number of arguments         */
  82.   const char *const argv[])           /* Array of pointers to args   */
  83. {
  84.   /*-----------------------------------------------------------------*/
  85.   /*  Local definitions.                                             */
  86.   /*-----------------------------------------------------------------*/
  87.  
  88.   int returncode ;
  89.  
  90.   static const char **posval[] = /* Ptrs to ptrs to posit'nal values */ 
  91.   {
  92.     &argptr
  93.   } ;
  94.  
  95.   static const char options[] =  /* Used to match option argument    */
  96.   {
  97.     'O',                            /* Overwrite mode                */
  98.     'P',                            /* Output prefix                 */
  99.     'R',                            /* Recursive mode                */
  100.     'T',                            /* Test mode                     */
  101.     '0'                             /* Null byte terminator          */
  102.   } ;
  103.  
  104.   static const char optflags[] = /* Used to set option flags         */
  105.   {
  106.     flgovr,                         /* Overwrite mode                */
  107.     0,                              /* Output prefix                 */
  108.     flgrcs,                         /* Recursive mode                */
  109.     flgtst,                         /* Test mode                     */
  110.   } ;
  111.  
  112.   static const char **optval[] = /* Ptrs to ptrs to option values    */
  113.   {
  114.     NULL,                           /* No value allowed              */
  115.     &pfxptr,                        /* Output file prefix            */
  116.     NULL,                           /* No value allowed              */
  117.     NULL,                           /* No value allowed              */
  118.   } ;
  119.  
  120.   static const char helpdata[] = /* Help text to be displayed        */
  121.  
  122.     "1stUnMake converts a 1stWord+ document file to a plain "
  123.     "text file by removing all the 1stWord+ control information "
  124.     "from the file.\x1f"
  125.     "\x1f"
  126.     "WARNING:\x01" "This utility converts files IN-PLACE if the "
  127.     "'-o' option is used to replace the 1stWord+ document with "
  128.     "the plain text output file.\x1f"
  129.     "\x1f"
  130.     "Syntax:\x01" "*1stUnMake  [path.]object  [options]\x1f"
  131.     "\x1f"
  132.     "object:\x01" "Specifies one of the following:\x1f"
  133.     "\x01" "(a) a single non-wildcarded file name\x1f"
  134.     "\x01" "(b) a single non-wildcarded directory name\x1f"
  135.     "\x01" "(c) a wildcarded name.\x1f"
  136.     "\x1f"
  137.     "\x01" "In case (a) the file is converted provided that it has a "
  138.     "file-type of 1WPDOC.\x1f"
  139.     "\x1f"
  140.     "\x01" "In case (b) all 1WPDOC files in the specified directory "
  141.     "are converted. If the RECURSION option is specified all files "
  142.     "in all subdirectories are also converted.\x1f"
  143.     "\x1f"
  144.     "\x01" "In case (c) all matching 1WPDOC files are converted. If "
  145.     "no matching files are found, then the first matching "
  146.     "directory name is taken and all 1WPDOC files therein are "
  147.     "converted. If the RECURSION option is specified, all matching "
  148.     "1WPDOC files are converted, plus all !WPDOC files in all "
  149.     "subdirectories.\x1f"
  150.     "\x1f"
  151.     "\x01" "In all cases, only files which have a filetype of 1WPDOC "
  152.     "(hex AF8) will be converted.\x1f"
  153.     "\x1f"
  154.     "path:\x01" "Specifies the directory to be searched for the "
  155.     "object file/directory. If omitted the current directory "
  156.     "is searched.\x1f"
  157.     "\x1f"
  158.     "options:\x01" "Specifies processing options which can be one "
  159.     "or more ofthe following:\x1f"
  160.     "\x1f"
  161.     "\x01" "-o\x02" "-\x03" "OVERWRITE mode; output file will have "
  162.     "same name and will replace input file.\x1f"
  163.     "\x1f"
  164.     "\x01" "-p xxx\x02" "-\x03" "specify PREFIX which will be used "
  165.     "to create name for output file if '-o' is not specified; "
  166.     "'xxx' can be one or more characters including directory "
  167.     "specification (e.g. 'txtdir.'); if not specified a default "
  168.     "of '_' is used.\x1f"
  169.     "\x1f"
  170.     "\x01" "-r\x02" "-\x03" "RECURSION mode which causes all eligible "
  171.     "files in all subdirectories to be converted.\x1f"
  172.     "\x1f"
  173.     "\x01" "-t\x02" "-\x03" "TEST mode; a list of files to be converted "
  174.     "is displayed but no output is actually written; useful for "
  175.     "checking when specifying a directory or wildcarded filename.\x1f"
  176.     "\x1f"
  177.     "1stUnMake - copyright Paul Witheridge, 1991\x1f"
  178.     "\x1f" ;
  179.  
  180.   static const unsigned char helptabs[] =  /* Help text tab settings */
  181.   {
  182.     1,10,17,19
  183.   } ;
  184.  
  185.   /*-----------------------------------------------------------------*/
  186.   /*  Executable statements                                          */
  187.   /*-----------------------------------------------------------------*/
  188.  
  189.   puts("\n1stUnMake Version 2.00 - 06 December 1991\n") ;
  190.  
  191.   /*-----------------------------------------------------------------*/
  192.   /*  Analyse arguments for file-name and option flags.              */
  193.   /*-----------------------------------------------------------------*/
  194.  
  195.   analargs(argc,argv,1,posval,options,&flags,optflags,optval) ;
  196.  
  197.   /*-----------------------------------------------------------------*/
  198.   /*  Set paged scrolling mode                                       */
  199.   /*-----------------------------------------------------------------*/
  200.  
  201.   _kernel_oswrch(12) ;
  202.   _kernel_oswrch(14) ;
  203.  
  204.   puts(" PRESS SHIFT KEY TO ALLOW WINDOW TO SCROLL\n") ;
  205.   
  206.   /*-----------------------------------------------------------------*/
  207.   /*  If no file name operand just display help text.                */
  208.   /*-----------------------------------------------------------------*/
  209.  
  210.   if ( argptr == NULL )
  211.   {
  212.     displaytext(helpdata,helptabs) ;
  213.     _kernel_oswrch(15) ;
  214.     return 0 ;
  215.   }
  216.  
  217.   /*-----------------------------------------------------------------*/
  218.   /*  If TEST MODE issue message.                                    */
  219.   /*-----------------------------------------------------------------*/
  220.  
  221.   if ( flags & flgtst )
  222.   {
  223.     puts("TEST MODE (files will be identified, not converted).\n") ;
  224.   }
  225.  
  226.   /*-----------------------------------------------------------------*/
  227.   /*  Invoke GetDirs function to read the directory entry(s) of the  */
  228.   /*  file(s) to be processed. Pass it a pointer of a processing     */
  229.   /*  function to be called.                                         */
  230.   /*-----------------------------------------------------------------*/
  231.  
  232.   returncode = 4 ;
  233.  
  234.   if ( getdirentrys(argptr,
  235.        ( flags & flgrcs ? RECURSE_ALWAYS : RECURSE_ONCE ),cnvtfunc) )
  236.   {
  237.     if ( flags & flgfnd )
  238.     {
  239.       printf("\n%d 1stWord+ document(s) ",filecount) ;
  240.       if ( flags & flgtst )
  241.       {
  242.         printf("would be ") ;
  243.       }
  244.       puts("converted.\n") ;
  245.       returncode = 0 ;
  246.     }
  247.     else
  248.     {
  249.       printf("No 1stWord+ documents found matching '%s'\n",argptr) ;
  250.       beep() ;
  251.     }
  252.   }
  253.   
  254.   /*-----------------------------------------------------------------*/
  255.   /*  Return to caller. All done.                                    */
  256.   /*-----------------------------------------------------------------*/
  257.  
  258.   _kernel_oswrch(15) ;
  259.   return returncode ;
  260. }
  261.  
  262. /*===================================================================*/
  263. /*                                                                   */
  264. /*  cnvtfunc  -  perform actual file conversion                      */
  265. /*  --------                                                         */
  266. /*                                                                   */
  267. /*  This function is called by the "getdirentrys" function for each  */
  268. /*  file-name that it encounters.                                    */
  269. /*                                                                   */
  270. /*  Only files which have a filetype of "text" (0xFFF) will be       */
  271. /*  processed.                                                       */
  272. /*                                                                   */
  273. /*===================================================================*/
  274.  
  275. static enum boolean cnvtfunc(
  276.   const char *path,                   /* Pointer to path name.       */
  277.   direntry *ptr)                      /* Pointer to direntry info.   */
  278. {
  279.   char *infile ;                      /* Ptr to path + leafname      */
  280.   char *oufile ;                      /* Ptr tp path + leafname      */
  281.   int result;                         /* Result from OS-File SWI     */
  282.   char *workarea ;                    /* Ptr to start of work area   */
  283.   char *workend ;                     /* Ptr to end of work area     */
  284.   char *iptr ;                        /* Working ptr to next char    */
  285.   char *optr ;                        /* Ptr to next output char     */
  286.   char *wptr ;                        /* Working pointer             */
  287.   int c ;                             /* Working character           */
  288.   int i ;                             /* Working integer             */
  289.  
  290.   _kernel_osfile_block osfileblock ;  /* OS File parameter block     */
  291.  
  292.   char footnotework[24] ;             /* Footnote workarea           */
  293.  
  294.   static const char overlapmsg[] =    /* Common error message        */
  295.     "Conversion overlap error in file '%s' - conversion failed\n" ;
  296.  
  297.   /*-----------------------------------------------------------------*/
  298.   /*  Executable statements                                          */
  299.   /*                                                                 */
  300.   /*  Return immediately if not a 1stWord+ document                  */
  301.   /*-----------------------------------------------------------------*/
  302.  
  303.   if ( ptr->type != 0xaf8 )
  304.   {
  305.     return TRUE ;
  306.   }
  307.  
  308.   /*-----------------------------------------------------------------*/
  309.   /*  If test mode just display file name                            */
  310.   /*-----------------------------------------------------------------*/
  311.  
  312.   if ( flags & flgtst )
  313.   {
  314.     if ( !(flags & flgfnd) )
  315.     {
  316.       puts("The following files would be converted:\n") ;
  317.       flags |= flgfnd ;
  318.     }
  319.     printf("%s%s\n",path,ptr->name) ;
  320.     filecount++ ;
  321.     return TRUE ;
  322.   }
  323.  
  324.   /*-----------------------------------------------------------------*/
  325.   /*  Create input and output filespecs                              */
  326.   /*-----------------------------------------------------------------*/
  327.   
  328.   if ( ( infile = malloc(2 * (strlen(path) + strlen(ptr->name) + 1)
  329.                          + strlen(pfxptr) ) ) == NULL )
  330.   {
  331.     puts("Out of memory") ;
  332.     return FALSE ;
  333.   } 
  334.   
  335.   oufile = infile + sprintf(infile,"%s%s",path,ptr->name) + 1 ;
  336.   sprintf(oufile,"%s%s%s",path,flags & flgovr ? "" : pfxptr,ptr->name) ;
  337.   
  338.   /*-----------------------------------------------------------------*/
  339.   /*  Check input file has non-zero length                           */
  340.   /*-----------------------------------------------------------------*/
  341.  
  342.   if ( ptr->length == 0 )
  343.   {
  344.     printf("'%s' is empty\n",infile) ;
  345.   }
  346.  
  347.   /*-----------------------------------------------------------------*/
  348.   /*  Allocate memory for file and load file                         */
  349.   /*-----------------------------------------------------------------*/
  350.  
  351.   if ( (workarea = malloc((ptr->length)+2) ) == NULL )
  352.   {
  353.     printf("'%s' too large to load",infile) ;
  354.     goto error4 ;
  355.   }
  356.   workend   = workarea + ptr->length + 1 ;
  357.  
  358.   osfileblock.load  = (int)(workarea + 1) ;
  359.   osfileblock.exec  = 0 ;
  360.   result = _kernel_osfile(16,infile,&osfileblock) ;
  361.  
  362.   if (result == _kernel_ERROR)
  363.   {
  364.     printf("'%s' load failed - %s\n",infile,
  365.           _kernel_last_oserror()->errmess) ;
  366.     goto error3 ;
  367.   }
  368.  
  369.   /*-----------------------------------------------------------------*/
  370.   /*  Convert document.                                              */
  371.   /*-----------------------------------------------------------------*/
  372.  
  373.   *workarea = '\0' ;
  374.   *workend  = '\n' ;
  375.   flags &= ALLON ^ (flgftn | flggrf) ;
  376.  
  377.   iptr = optr = workarea + 1 ;
  378.  
  379.   while ( iptr < workend ) 
  380.   {
  381.     switch ( c = *iptr )
  382.     {
  383.       /*-------------------------------------------------------------*/
  384.       /*  0A = newline - truncate trailing blanks                    */
  385.       /*-------------------------------------------------------------*/
  386.  
  387.       case 0x0a :
  388.  
  389.         for ( optr-- ; *optr == ' ' ; optr-- ) ;
  390.         optr++ ;
  391.         *(optr++) = '\n' ;
  392.         break ;
  393.       
  394.       /*-------------------------------------------------------------*/
  395.       /*  0B = keep - followed by 1 byte line count (+0x10)          */
  396.       /*              discard both bytes                             */
  397.       /*-------------------------------------------------------------*/
  398.  
  399.       case 0x0b : 
  400.  
  401.         iptr++ ;
  402.         break ;
  403.       
  404.       /*-------------------------------------------------------------*/
  405.       /*  0C = hard new page - discard byte                          */
  406.       /*-------------------------------------------------------------*/
  407.       
  408.       case 0x0c :
  409.  
  410.         break ;
  411.     
  412.       /*-------------------------------------------------------------*/
  413.       /*  18 = footnote ref - followed footnote line count,          */
  414.       /*       a comma, the footnote number and another byte         */
  415.       /*       of 0x18                                               */
  416.       /*-------------------------------------------------------------*/
  417.  
  418.       case 0x18 :
  419.  
  420.         if ( sscanf(iptr+1,"%*d,%d%c",&i,&footnotework[0]) != 2 ||
  421.              footnotework[0] != 0x18 )
  422.         {
  423.           printf("Invalid footnote reference in file '%s'\n",
  424.                  infile) ;
  425.           goto noconversion ;
  426.         }
  427.         iptr = strchr(iptr+1,0x18) ;
  428.         if ( !footnotewarning(infile) )
  429.         {
  430.           goto noconversion ;
  431.         }
  432.         i = sprintf(footnotework,"[%d]",i) ;
  433.         memcpy(optr,footnotework,i) ;
  434.         optr += i ;
  435.         if ( optr > iptr )
  436.         {
  437.           printf(overlapmsg,infile) ;
  438.           goto noconversion ;
  439.         }
  440.         break ;
  441.       
  442.       /*-------------------------------------------------------------*/
  443.       /*  19 = soft hyphen - replace by hyphen                       */
  444.       /*-------------------------------------------------------------*/
  445.  
  446.       case 0x19 :
  447.  
  448.         *(optr++) = '-' ;
  449.         break ;
  450.       
  451.       /*-------------------------------------------------------------*/
  452.       /*  1B = font specification - followed by one byte of          */
  453.       /*       flags indicating font combination required;           */
  454.       /*       discard both bytes                                    */
  455.       /*-------------------------------------------------------------*/
  456.  
  457.       case 0x1b :
  458.  
  459.         iptr++ ;
  460.         break ;
  461.       
  462.       /*-------------------------------------------------------------*/
  463.       /*  1C, 1D, 1E = indent, stretch and soft spaces;              */
  464.       /*               replace by blank                              */
  465.       /*-------------------------------------------------------------*/
  466.  
  467.       case 0x1c :
  468.       case 0x1d :
  469.       case 0x1e :
  470.  
  471.         *(optr++) = ' ' ;
  472.         break ;
  473.  
  474.       /*-------------------------------------------------------------*/
  475.       /*  1F = full line of control info                             */
  476.       /*                                                             */
  477.       /*       x01f N  =  start of footnote                          */
  478.       /*       x01f E  =  end of footnotes                           */
  479.       /*       x01f 8  =  graphics                                   */
  480.       /*                                                             */
  481.       /*  Other types are just skipped                               */
  482.       /*-------------------------------------------------------------*/
  483.  
  484.       case 0x1f :
  485.  
  486.         wptr = iptr ;
  487.  
  488.         iptr = memchr(iptr,'\n',INT_MAX) ;
  489.            
  490.         switch ( *(wptr + 1) )
  491.         {
  492.           case 'N' :  /* Footnote header */
  493.  
  494.             if ( sscanf(wptr+2,"%3d",&i) != 1 )
  495.             {
  496.               printf("Invalid footnote in file '%s'\n",infile) ;
  497.               goto noconversion ;
  498.             }
  499.             if ( !footnotewarning(infile) )
  500.             {
  501.               goto noconversion ;
  502.             }
  503.             i = sprintf(footnotework,"**Footnote [%d]\n",i) ;
  504.             memcpy(optr,footnotework,i) ;
  505.             optr += i ;
  506.             if ( optr > iptr )
  507.             {
  508.               printf(overlapmsg,infile) ;
  509.               goto noconversion ;
  510.             }
  511.             break ;
  512.  
  513.           case 'E' :  /* Footnote trailer */
  514.  
  515.             if ( !footnotewarning(infile) )
  516.             {
  517.               goto noconversion ;
  518.             }
  519.             memcpy(optr,"**End footnote(s)\n",18) ;
  520.             optr += 18 ;
  521.             if ( optr > iptr )
  522.             {
  523.               printf(overlapmsg,infile) ;
  524.               goto noconversion ;
  525.             }
  526.             break ;
  527.  
  528.           case '8' :  /* Name of sprite file */
  529.  
  530.             if ( !(flags & flggrf) )
  531.             {
  532.               flags |= flggrf ;
  533.               if ( flags & flgovr )
  534.               {
  535.                 printf("Graphics found in file '%s' - "
  536.                        "REPLACE (-o) option in effect - "
  537.                        "file will not be converted\n",
  538.                        infile) ;
  539.                 goto noconversion ;
  540.               }
  541.               else
  542.               {
  543.                 printf("WARNING - graphics found in file '%s'\n",
  544.                        infile) ;
  545.               }
  546.             }
  547.             *iptr = '\0' ;
  548.             strncpy(footnotework,wptr+11,sizeof(footnotework)-1) ;
  549.             footnotework[sizeof(footnotework)-1] = '\0' ;
  550.             optr += sprintf(optr,"**Graphics [%s]\n",footnotework) ;
  551.             if ( optr > iptr )
  552.             {
  553.               printf(overlapmsg,infile) ;
  554.               goto noconversion ;
  555.             }
  556.             break ;
  557.           }
  558.  
  559.         break ;
  560.       
  561.       /*-------------------------------------------------------------*/
  562.       /*  Keep all remaining characters. Issue warning if            */
  563.       /*  any other CTRL characters found.                           */
  564.       /*-------------------------------------------------------------*/
  565.       
  566.       default :
  567.  
  568.         if ( iscntrl(c) )
  569.         {
  570.           printf("WARNING - CTRL [%2.2d] character "
  571.                  "encountered in file '%s'\n",
  572.                  c,infile) ;
  573.         }
  574.         *(optr++) = c ;
  575.  
  576.     }
  577.     iptr++ ;
  578.   }
  579.  
  580.   /*-----------------------------------------------------------------*/
  581.   /*  Save modified file                                             */
  582.   /*-----------------------------------------------------------------*/
  583.  
  584.   osfileblock.start = (int)(workarea + 1) ;
  585.   osfileblock.end   = (int)optr ;
  586.   osfileblock.load  = 0xfff ;
  587.  
  588.   result = _kernel_osfile(10,oufile,&osfileblock) ;
  589.  
  590.   if (result == _kernel_ERROR)
  591.   {
  592.     printf("'%s' save failed - %s\n",oufile,
  593.           _kernel_last_oserror()->errmess);
  594.     goto error3 ;
  595.   }
  596.  
  597.   /*-----------------------------------------------------------------*/
  598.   /*  Valid numbered text file - bump file count                     */
  599.   /*-----------------------------------------------------------------*/
  600.   
  601.   filecount++ ;
  602.   flags |= flgfnd ;
  603.  
  604.   /*-----------------------------------------------------------------*/
  605.   /*  Display file name                                              */
  606.   /*-----------------------------------------------------------------*/
  607.  
  608.   printf("'%s' converted",infile) ;
  609.   if ( !(flags & flgovr) )
  610.   {
  611.     printf(" and saved as '%s'",oufile) ;
  612.   }
  613.   putchar('\n') ;
  614.  
  615.   /*-----------------------------------------------------------------*/
  616.   /*  Free work area and return with good completion code            */
  617.   /*-----------------------------------------------------------------*/
  618.  
  619.   noconversion:
  620.  
  621.     free(workarea) ;
  622.     free(infile) ;
  623.     
  624.     return TRUE ;
  625.  
  626.   /*-----------------------------------------------------------------*/
  627.   /*  Error exits                                                    */
  628.   /*-----------------------------------------------------------------*/
  629.  
  630.   error3: free(workarea) ;
  631.   error4: free(infile) ;
  632.           beep() ;
  633.  
  634.     return FALSE ;
  635. }
  636.  
  637. /*===================================================================*/
  638. /*  footnotewarning  -  issue warning message about footnotes        */
  639. /*===================================================================*/
  640.  
  641. static enum boolean footnotewarning(
  642.   const char *filenameptr)             /* Ptr to filename            */
  643. {
  644.   if ( flags & flgovr )
  645.   {
  646.     printf("Footnotes found in file '%s' - REPLACE (-o) option in "
  647.            "effect - file will not be converted\n",filenameptr) ;
  648.     return FALSE ;
  649.   }
  650.  
  651.   if ( !(flags & flgftn) )
  652.   {
  653.     printf("WARNING - footnotes found in file '%s'\n",filenameptr) ;
  654.     flags |= flgftn ;
  655.   }
  656.  
  657.   return TRUE ;
  658. }
  659.  
  660. /*===================================================================*/
  661.